home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 7 / FM Towns Free Software Collection 7.iso / data / happysrc / paasm.c < prev    next >
Text File  |  1993-11-30  |  27KB  |  773 lines

  1. /**********************************************************************
  2.  *
  3.  *       *** HAPPy Pascal Compiler ***
  4.  *               P-code assmebler
  5.  *
  6.  *           Copyright (c) H.Asano 1992,1993
  7.  *
  8.  **********************************************************************/
  9.  
  10. #define EXTERN extern
  11. #define Maxlabel   1800                 /* 最大ラベル数               */
  12.  
  13. #include <float.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include "version.h"
  18. #include "hapai.h"
  19.  
  20. /********* co-operation table **********/
  21. static char cop[] =
  22.   {
  23.    /*          x0    x1    x2    x3    x4    x5    x6    x7    x8    x9   */
  24.    /* 0x */    115,  105,   70,   75,    0,    0,   80,    0,    0,   85,
  25.    /* 1x */      0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.    /* 2x */      0,    0,    0,    0,    0,    0,   95,    0,    0,    0,
  27.    /* 3x */      0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  28.    /* 4x */      0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  29.    /* 5x */      0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  30.    /* 6x */      0,    0,    0,    0,    0,    0,    0,    0,    0,    0
  31.   } ;
  32.  
  33.  
  34. /***************************************/
  35. /* P-code 標準手続き・関数ニーモニック表*/
  36. /***************************************/
  37. static char sptable[][4] =
  38. {
  39.    /*          x0    x1    x2    x3    x4    x5    x6    x7    x8    x9  */
  40.    /* 0x */  "get","put","rst","rln","new","wln","wrs","wrb","wri","wrr",
  41.    /* 1x */  "wrc","rdi","rdr","rdc","sin","cos","exp","log","sqt","atn",
  42.    /* 2x */  "pge","eof","eol","dis","wrf","rwt","trs","trw","tgt","tpt"
  43. } ;
  44.  
  45. /***************************************/
  46. /*            ラベル表                 */
  47. /***************************************/
  48. enum lbst {  entered,                   /* ラベル未登録の状態         */
  49.              defined                    /* ラベル定義済の状態         */
  50.           };
  51.  
  52. static struct  {
  53.   int val               ;               /* value                      */
  54.   enum lbst st          ;               /* status {enterd,defined}    */
  55. } labeltab[Maxlabel]    ;
  56.  
  57. /***************************************/
  58. /*      仮想計算機 記憶装置            */
  59. /***************************************/
  60. static _store store[Maxstore] ;
  61.  
  62. /***************************************/
  63. /*            変数定義                 */
  64. /***************************************/
  65. static char *PcodeSourceName;           /* P-codeソースファイル名      */
  66. static char *CompVersion    ;           /* コンパイラのバージョン     */
  67. static FILE *pcsfile        ;           /* P-codeソースファイルポインタ         */
  68. static FILE *objfile        ;           /* P-codeオブジェクトファイルポインタ    */
  69. static int  codesize        ;           /* コードのワードサイズ           */
  70. static int  objsize         ;           /* オブジェクト全体のワードサイズ */
  71. static int  labelvalue      ;           /* labelの値                  */
  72. static char ch              ;           /* 読込文字                   */
  73. static int  intch           ;           /* 読込処理内での読込文字     */
  74. static int            pc    ;           /* program counter            */
  75. static char           op    ;           /* P-code operation           */
  76. static char           p     ;           /* P-code p operand           */
  77. static int            q     ;           /* P-code q operand           */
  78. static int start = -1       ;           /* オブジェクト開始の合図     */
  79.  
  80. /*********************************************************************/
  81.  
  82. /***************************************/
  83. /*     エラーメッセージ出力処理        */
  84. /***************************************/
  85. static void paerr(int errno)
  86. {
  87.   static struct _errmsg {
  88.        int  msgno       ;               /* error message number       */
  89.        char *errmsg     ;               /* error message              */
  90.      } errtb[]  =  {
  91.  
  92.    {1,  "命令数が多すぎてアセンブルできない"},
  93.    {2,  "オブジェクトファイルがオープンできない"},
  94.    {3,  "オブジェクトファイル書き込みでエラーが発生した"},
  95.    {4,  "ラベル数が多すぎてアセンブルできない"},
  96.    {5,  "定数を格納するメモリを使い果たしてアセンブルできない"},
  97.    {6,  "P-codeソースファイルがオープンできない"},
  98.    {7,  "PC.EXEとPA.OVLのバージョンが違う"}
  99. } ;
  100.   int i = -1 ;
  101.  
  102.      while(errtb[++i].msgno != errno) ; /* search message             */
  103.      fprintf(stderr,"A%03d: %s\n", errno, errtb[i].errmsg);
  104.      exit(3) ;                          /* アセンブルエラーで停止     */
  105. }
  106.  
  107. /***************************************/
  108. /*      reset() : reset関数            */
  109. /***************************************/
  110. static void reset(char *filename)
  111. {
  112.  
  113.      pcsfile = fopen(filename,"r") ;
  114.      if(pcsfile == NULL) paerr(6) ;
  115.  
  116.      intch =  getc(pcsfile)  ;          /* 1文字先読み                */
  117. }
  118.  
  119. /***************************************/
  120. /*       eoln() : eolnマクロ定義       */
  121. /***************************************/
  122. #define eoln()   (intch == '\n')        /* 改行を読んでいれば真       */
  123.  
  124. /***************************************/
  125. /* readc() : char型read処理            */
  126. /***************************************/
  127. static char readc(void)
  128. {
  129.   int oldch ;
  130.  
  131.      oldch    = intch     ;
  132.      intch    = getc(pcsfile) ;
  133.      return((char)oldch)  ;
  134. }
  135.  
  136. /***************************************/
  137. /*   readi() : integer型入力処理       */
  138. /***************************************/
  139. static integer readi(void)
  140. {
  141.   integer  ival = 0 ;
  142.   int      sign = 1 ;
  143.  
  144.      if(intch == ' ')
  145.       while((intch = getc(pcsfile)) == ' '); /* 空白読み飛ばし        */
  146.  
  147.      if((intch=='+') || (intch=='-')) {  /* 符号の時                  */
  148.       sign = (intch=='+') ? 1 : -1  ;    /* 符号に応じた正負          */
  149.       intch  = getc(pcsfile) ;
  150.      }
  151.  
  152.      do {
  153.       intch -= '0' ;
  154.       ival = ival*10 + intch ;
  155.       if(eoln()) break ;                /* EOLNならばそこまで         */
  156.       intch=getc(pcsfile) ;
  157.      } while(('0' <= intch) && (intch <= '9')) ;
  158.  
  159.      return(sign*ival) ;
  160. }
  161.  
  162. /***************************************/
  163. /*   readr() : real型入力処理          */
  164. /***************************************/
  165. static float readr(void)
  166. {
  167.   char buf[20] ;
  168.   int  i = 0   ;
  169.  
  170.      while(intch == ' ') intch = getc(pcsfile) ;   /* 空白読み飛ばし */
  171.      do {
  172.       buf[i++] = (char)intch ;
  173.       intch = getc(pcsfile) ;
  174.      } while (intch != '\n') ;
  175.      buf[i] = '\0' ;
  176.  
  177.      return((float)atof(buf)) ;         /* 浮動小数点へ変換           */
  178. }
  179.  
  180. /***************************************/
  181. /* readln() : EOLまで読み飛ばす処理    */
  182. /***************************************/
  183. static void readln(void)
  184. {
  185.      while(!eoln()) intch = getc(pcsfile) ;
  186.      intch = getc(pcsfile);
  187. }
  188.  
  189. /***************************************/
  190. /*    オブジェクトファイル書出処理     */
  191. /***************************************/
  192. static void putobject(char *area, int size)
  193. {
  194.       fwrite(area,size,1,objfile) ;
  195.       if(ferror(objfile)) paerr(3) ;    /* 書き込み失敗               */
  196. }
  197.  
  198. /***************************************/
  199. /*          初期設定処理               */
  200. /***************************************/
  201. static void init(void)
  202. {
  203.   int i;
  204.  
  205.      _fpreset() ;                      /* 浮動小数点パッケージ初期設定*/
  206.      for(i=0;i<Maxlabel;i++) {          /* ラベル表 の 初期設定       */
  207.       labeltab[i].val = -1 ;
  208.       labeltab[i].st  = entered;
  209.      }
  210.  
  211.      reset(PcodeSourceName) ;           /* P-codeソースファイルのオープン       */
  212.  
  213.      objfile = fopen("pcode.pco","wb") ;/* ファイルオープン           */
  214.      if(objfile == NULL) paerr(2) ;     /* オープンできない           */
  215.  
  216.      if(codesize > Maxstore)           /* 記憶装置の大きさより大きい時*/
  217.       paerr(1) ;                        /* プログラム停止                */
  218.  
  219.      if(strcmp(CompVersion,version))
  220.       paerr(7) ;                        /* バージョン不一致           */
  221.  
  222.      putobject(version,strlen(version)+1) ; /* バージョン番号書出     */
  223.  
  224.      objsize = codesize ;
  225. }
  226.  
  227. /***************************************/
  228. /*    ラベル表登録処理                 */
  229. /***************************************/
  230. static void update(int x)
  231. {                                       /*  x: label名                */
  232.    int curr,succ ;
  233.  
  234.      if(x > Maxlabel-1) paerr(4) ;      /* ラベル数が多すぎる         */
  235.  
  236.      if(labeltab[x].val != -1) {        /* 前方参照されている時       */
  237.       curr = labeltab[x].val;
  238.       for(;;) {
  239.        succ = store[curr].vo.cdq;
  240.        store[curr].vo.cdq = labelvalue;
  241.        if(succ == -1)  break;           /* 終了                       */
  242.        else            curr = succ;
  243.       }
  244.      }
  245.      labeltab[x].st  = defined    ;
  246.      labeltab[x].val = labelvalue ;
  247. }
  248.  
  249. /***************************************/
  250. /*     ラベル値決定処理                */
  251. /***************************************/
  252. static void lookup(int x)
  253. {
  254.      if(labeltab[x].st == entered) {    /* 未定義                     */
  255.       q = labeltab[x].val     ;         /* 初期値のまま -1           */
  256.       labeltab[x].val = pc    ;         /* 今のpcを格納               */
  257.      }
  258.      else q = labeltab[x].val ;         /* 定義済の時                 */
  259. }
  260.  
  261. /***************************************/
  262. /*     ラベル値読込処理                */
  263. /***************************************/
  264. static void labelsearch(void)
  265. {
  266.      while(ch != 'L')                   /* 'L' まで 読み飛ばし        */
  267.       ch = readc() ;
  268.      lookup((int)readi());              /* labelを読み 値を探す       */
  269. }
  270.  
  271.  
  272. /********* typesymbol() : instruction名4文字目によってopを決定する *********/
  273. static void typesymbol(void)
  274. {
  275.    int i;
  276.  
  277.      switch(ch) {
  278.       case 'i' : return ;       /* 'i' の時は opはそのまま */
  279.       case 'a' : i=0; break;
  280.       case 'r' : i=1; break;
  281.       case 's' : i=2; break;
  282.       case 'b' : i=3; break;
  283.       case 'c' : i=4;
  284.      }
  285.      op=cop[op]+i;             /* opの変更 */
  286. }
  287.  
  288. /**************************************/
  289. /* PTN0() : オペランドのない命令      */
  290. /**************************************/
  291. static void PTN0(void)
  292. {
  293. }
  294.  
  295. /**************************************/
  296. /* PTN1() : lod,strのアセンブル       */
  297. /**************************************/
  298. static void PTN1(void)
  299. {
  300.      typesymbol() ;
  301.      p=(char)readi() ;
  302.      q=(int)readi() ;
  303. }
  304.  
  305. /**************************************/
  306. /* PTN2() : lda,movのアセンブル       */
  307. /**************************************/
  308. static void PTN2(void)
  309. {
  310.      p=(char)readi() ;
  311.      q=(int)readi() ;
  312. }
  313.  
  314. /***************************************/
  315. /* PTN3() : mst,cui,bas,traのアセンブル*/
  316. /***************************************/
  317. static void PTN3(void)
  318. {
  319.      p=(char)readi() ;
  320. }
  321.  
  322. /**************************************/
  323. /* PTN4() : cup,ent,ejpのアセンブル   */
  324. /**************************************/
  325. static void PTN4(void)
  326. {
  327.      p=(char)readi() ;
  328.      labelsearch();
  329. }
  330.  
  331. /************************************************/
  332. /* PTN5() : equ,neq,geq,grt,leq,lesのアセンブル */
  333. /************************************************/
  334. static void PTN5(void)
  335. {
  336.      switch(ch) {
  337.       case 'a' :     ; break ;
  338.       case 'i' : p=1 ; break ;
  339.       case 'r' : p=2 ; break ;
  340.       case 'b' : p=3 ; break ;
  341.       case 's' : p=4 ; break ;
  342.       case 'c' : p=6 ; break ;
  343.       case 'm' : p=5 ;
  344.       q=(int)readi() ;
  345.      }
  346. }
  347.  
  348. /**************************************/
  349. /* PTN6() : ldo,sroのアセンブル       */
  350. /**************************************/
  351. static void PTN6(void)
  352. {
  353.      typesymbol() ;
  354.      q=(int)readi();
  355. }
  356.  
  357. /**************************************/
  358. /* PTN7() : inc,decのアセンブル       */
  359. /**************************************/
  360. static void PTN7(void)
  361. {
  362.      switch(ch) {
  363.       case 'a' :/*p=0*;*/ break ;
  364.       case 'i' :  p=1;    break ;
  365.       case 'r' :  p=2;    break ;
  366.       case 'b' :  p=3;    break ;
  367.       case 'c' :  p=6;    break ;
  368.      }
  369.      q = (int)readi() ;
  370. }
  371.  
  372. /****************************************/
  373. /* PTN8() : ujp,fjp,xjp,lapのアセンブル */
  374. /****************************************/
  375. static void PTN8(void)
  376. {
  377.      labelsearch() ;
  378. }
  379.  
  380. /**************************************/
  381. /* CHK() : chkのアセンブル            */
  382. /**************************************/
  383. static void CHK(void)
  384. {
  385.    integer  lb,ub ;
  386.  
  387.      typesymbol() ;
  388.      p = (char)readi() ;                /* チェック種別              */
  389.      lb = readi();                      /* 下限値                     */
  390.      ub = readi();                      /* 上限値                     */
  391.      store[objsize  ].vi = lb ;
  392.      store[objsize+1].vi = ub ;
  393.      q=codesize;
  394.      do {
  395.       q++ ;
  396.      } while((store[q-1].vi != lb) || (store[q].vi != ub)) ;
  397.      if(q   == objsize) objsize++    ;  /* 最後に1つだけ定数追加の時  */
  398.      if(q-1 == objsize) objsize += 2 ;  /* 最後に2つの  対数追加の時  */
  399.      if(objsize>=Maxstore) paerr(5)  ;  /* 定数格納不可               */
  400. }
  401.  
  402. /**************************************/
  403. /* CSP() : cspのアセンブル            */
  404. /**************************************/
  405. static void CSP(void)
  406. {
  407.    char name[4];
  408.  
  409.      do ;
  410.      while((ch=readc())==' ') ;         /* 空白を読み飛ばし           */
  411.      *name     = ch       ;             /* 1文字目                    */
  412.      *(name+1) = readc()  ;             /* 2文字目                    */
  413.      *(name+2) = readc()  ;             /* 3文字目                    */
  414.      *(name+3) = '\0'     ;
  415.      while(strcmp(sptable[q],name) != 0)/*対応のqをサーチ             */
  416.       q++ ;
  417. }
  418.  
  419. /**************************************/
  420. /* IND() : indのアセンブル            */
  421. /**************************************/
  422. static void IND(void)
  423. {
  424.      typesymbol() ;
  425.      q=(int)readi() ;
  426. }
  427.  
  428. /**************************************/
  429. /* IXA() : ixaのアセンブル            */
  430. /**************************************/
  431. static void IXA(void)
  432. {
  433.   integer lb,ub ;
  434.  
  435.      lb = readi() ;                     /* 下限値                     */
  436.      ub = readi() ;                     /* ixa値                      */
  437.      store[objsize  ].vi = lb ;
  438.      store[objsize+1].vi = ub ;
  439.      q=codesize;
  440.      do {
  441.       q++ ;
  442.      } while((store[q-1].vi != lb) || (store[q].vi != ub)) ;
  443.      if(q   == objsize) objsize++    ;  /* 最後に1つだけ定数追加の時  */
  444.      if(q-1 == objsize) objsize += 2 ;  /* 最後に2つの  対数追加の時  */
  445.      if(objsize>=Maxstore) paerr(5)  ;  /* 定数格納不可               */
  446. }
  447.  
  448. /**************************************/
  449. /* LAO() : laoのアセンブル            */
  450. /**************************************/
  451. static void LAO(void)
  452. {
  453.      q=(int)readi();
  454. }
  455.  
  456. /**************************************/
  457. /* LCA() : lcaのアセンブル            */
  458. /**************************************/
  459. static void LCA(void)
  460. {
  461.      q=objsize;
  462.      readc() ;                          /* "を読み飛ばす              */
  463.      ch=readc() ;                       /* "の次の文字                */
  464.      while(ch != '\"') {
  465.       store[objsize++].vc = (unsigned char)ch ;
  466.       if(objsize>=Maxstore)
  467.        paerr(5) ;                       /* 定数格納不可               */
  468.       ch=readc() ;                      /* 次の文字                   */
  469.      }
  470. }
  471.  
  472. /**************************************/
  473. /* LDC() : ldcのアセンブル            */
  474. /**************************************/
  475. static void LDC(void)
  476. {
  477.   integer lnumber ;
  478.   float   rnumber ;
  479.   long    s,s1    ;
  480.  
  481.      switch(ch) {
  482.       case 'i' : p=1 ;                  /* integer type               */
  483.                  lnumber = readi() ;
  484.                  if(labs(lnumber) < (long)Largeint)
  485.                   q = (int)lnumber;
  486.                  else {                 /* 大きな数の時               */
  487.                   op = 66 ;             /* lci命令に変更              */
  488.                   store[objsize].vi = lnumber ;
  489.                   q=codesize-1;
  490.                   do ;
  491.                   while(store[++q].vi != lnumber) ;
  492.                   if(q == objsize) {
  493.                    objsize++  ;
  494.                    if(objsize>=Maxstore)
  495.                     paerr(5) ;          /* 定数格納不可               */
  496.                   }
  497.                  }
  498.                  break ;
  499.  
  500.       case 'c' : p=6 ;                  /* char type                  */
  501.                  while((ch=readc())==' ') ;
  502.                  q=readc() ;
  503.                  break ;
  504.  
  505.       case 'b' : p=3;                   /* boolean                    */
  506.                  q=(int)readi() ;
  507.                  break;
  508.  
  509.       case 'n' : p=0 ;                  /* ldc nil                    */
  510.                  q=0 ;
  511.                  break ;
  512.  
  513.       case 's' : p  = 4;                /* set type                   */
  514.                  s=0;
  515.                  while(readc() != '(') ;
  516.                  ch=readc() ;
  517.                  while(ch!=')') {
  518.                   s1=(int)readi() ;
  519.                   addset(s,s1)  ;
  520.                   ch=readc()   ;
  521.                  }
  522.                  store[objsize].vs = s ;
  523.                  q = codesize ;
  524.                  while(store[q].vs != s) q++ ;
  525.                  if(q==objsize) {
  526.                   objsize++ ;
  527.                   if(objsize>=Maxstore)
  528.                    paerr(5) ;           /* 定数格納不可               */
  529.                  }
  530.                  break ;
  531.  
  532.       case 'r' : p = 2 ;
  533.                  rnumber = readr() ;
  534.                  store[objsize].vr = rnumber ;
  535.                  lnumber = store[objsize].vi ;
  536.                  /* 浮動小数点の形で比較を行うと思わぬ落とし穴があるので
  537.                    ビット列の比較をするために、union型のviから数を得る*/
  538.                  q=codesize-1;
  539.                  do ;
  540.                  while(store[++q].vi != lnumber) ;
  541.                  if(q == objsize) {
  542.                   objsize++  ;
  543.                   if(objsize>=Maxstore)
  544.                    paerr(5) ;           /* 定数格納不可               */
  545.                  }
  546.                  break ;
  547.      }
  548. }
  549.  
  550. /**************************************/
  551. /* ORD() : ordのアセンブル            */
  552. /**************************************/
  553. static void ORD(void)
  554. {
  555.      switch(ch) {
  556.       case 'b' : p=3 ; break ;
  557.       case 'c' : p=6 ;
  558.      }
  559. }
  560.  
  561. /**************************************/
  562. /* RET() : retのアセンブル            */
  563. /**************************************/
  564. static void RET(void)
  565. {
  566.      switch(ch) {
  567.       case 'p' :     ; break ;
  568.       case 'i' : p=1 ; break ;
  569.       case 'r' : p=2 ; break ;
  570.       case 'c' : p=3 ; break ;
  571.       case 'b' : p=4 ; break ;
  572.       case 'a' : p=5 ; break ;
  573.      }
  574. }
  575.  
  576. /**************************************/
  577. /* STO() : stoのアセンブル            */
  578. /**************************************/
  579. static void STO(void)
  580. {
  581.      typesymbol() ;
  582. }
  583.  
  584. /**********************************************************************/
  585. /*                   P-code ニーモニック表                            */
  586. /**********************************************************************/
  587. static char instr[][4] =
  588. {
  589.    /*          x0    x1    x2    x3    x4    x5    x6    x7    x8    x9  */
  590.    /* 0x */  "lod","ldo","str","sro","lda","lao","sto","ldc","bas","ind",
  591.    /* 1x */  "inc","mst","cup","ent","ret","csp","ixa","equ","neq","geq",
  592.    /* 2x */  "grt","leq","les","ujp","fjp","xjp","chk","lap","adi","adr",
  593.    /* 3x */  "sbi","sbr","sgs","flt","flo","trc","ngi","ngr","sqi","sqr",
  594.    /* 4x */  "abi","abr","not","and","ior","dif","int","uni","inn","mod",
  595.    /* 5x */  "odd","mpi","mpr","dvi","dvr","mov","lca","dec","stp","ord",
  596.    /* 6x */  "chr","ujc","mms","msi","cui","ejp","...","cka","tra","rou"
  597. } ;                                         /*    ↑ ここはlci */
  598.  
  599. /******* ニーモニック対応のエントリ表 ********/
  600. static struct entry {
  601.        void (*func)(void) ;
  602. } OP[] = {
  603.    /*          x0    x1    x2    x3    x4    x5    x6    x7    x8    x9  */
  604.    /* 0x */   PTN1, PTN6 ,PTN2, PTN6, PTN2, LAO , STO , LDC , PTN3, IND ,
  605.    /* 1x */   PTN7, PTN3, PTN4, PTN4, RET , CSP , IXA , PTN5, PTN5, PTN5,
  606.    /* 2x */   PTN5, PTN5, PTN5, PTN8, PTN8, PTN8, CHK , PTN8, PTN0, PTN0,
  607.    /* 3x */   PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0,
  608.    /* 4x */   PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0,
  609.    /* 5x */   PTN0, PTN0, PTN0, PTN0, PTN0, PTN2, LCA , PTN7, PTN0, ORD ,
  610.    /* 6x */   PTN0, PTN0, PTN0, PTN0, PTN3, PTN4, PTN0, PTN0, PTN3, PTN0
  611. } ;
  612.  
  613. /***************************************/
  614. /*     1行アセンブル処理               */
  615. /***************************************/
  616. static void assemble(void)
  617. {
  618.    char name[4];
  619.  
  620.      *name     = ch       ;            /* 1文字目 */
  621.      *(name+1) = readc()  ;            /* 2文字目 */
  622.      *(name+2) = readc()  ;            /* 3文字目 */
  623.      *(name+3) = '\0'     ;
  624.      if(!eoln()) ch=readc();
  625.       /* そこで行が終わってなければ次の文字を読む */
  626.  
  627.      op = -1 ;
  628.      while(strcmp(instr[++op],name)) ;  /* instructionよりopを決定    */
  629.          /* このようなリニアサーチはスピードが遅いので改良しよう      */
  630.  
  631.      p   =  0 ;
  632.      q   =  0 ;
  633.      OP[op].func() ;                    /* opに対応したアセンブル     */
  634.  
  635.      store[pc  ].vo.cdop = op;          /* code table へ 格納        */
  636.      store[pc  ].vo.cdp  = p ;
  637.      store[pc++].vo.cdq  = q ;
  638. }
  639.  
  640. /********** generate() :  行の最初に呼ばれる処理 **********/
  641. static void generate(void)
  642. {
  643.    int x     ;                          /* label値                    */
  644.    int i     ;                          /* 作業カウンタ               */
  645.    char progname[33] ;                  /* プログラム名               */
  646.    char filename[33] ;                  /* ファイル名                 */
  647.    int fileadr       ;                  /* ファイルアトレス           */
  648.    int filesize      ;                  /* バッファ変数の大きさ       */
  649.  
  650.      for(;;) {
  651.       ch=readc();                       /* 行の最初の文字を読む       */
  652.       switch(ch) {
  653.        case 'Q' : return ;              /* アセンブル終わり           */
  654.  
  655.        case 'N' :                       /* プログラム名               */
  656.                   readc() ;             /* 空白を読み飛ばす           */
  657.                   i=0 ;
  658.                   while(!eoln())        /* プログラム名取得           */
  659.                    progname[i++] = readc() ;
  660.                   progname[i] = '\0' ;
  661.                   putobject(progname,i+1) ; /* 書出                   */
  662.                   break ;
  663.  
  664.        case 'F' :                       /* ファイルアドレス           */
  665.                   readc() ;             /* 空白を読み飛ばす           */
  666.                   i=0 ;
  667.                   while((ch=readc()) != ' ') /* ファイル名取得        */
  668.                    filename[i++] = ch ;
  669.                   filename[i] = '\0'  ;
  670.                   readc() ;                       /*  空白を読み飛ばす*/
  671.                   fileadr = (int)readi() ;        /* ファイルアトレス */
  672.                   putobject((char*)&fileadr,sizeof(fileadr));/* 書出  */
  673.                   filesize = (int)readi();        /* バッファサイズ   */
  674.                   putobject((char*)&filesize,sizeof(filesize));/* 書出*/
  675.                   putobject(filename,i+1) ;       /* ファイル名書出   */
  676.                   break ;
  677.  
  678.        case ';' :                       /* 注釈行を無視               */
  679.                   break ;
  680.        case 'L' : x=(int)readi();       /* label名を読む              */
  681.                   if(!eoln()) ch=readc() ;
  682.                   if(ch=='=') labelvalue=(int)readi();
  683.                                                    /* label値がある時 */
  684.                   else         labelvalue=pc;      /* ない時はpcの値  */
  685.                   update(x);                       /* label登録       */
  686.                   break ;
  687.        case ' ' : ch=readc();        /* 空白の時は その行をアセンブル */
  688.                   assemble();
  689.        default  : ;
  690.       }
  691.       readln() ;
  692.      }
  693. }
  694.  
  695. /*****************************************/
  696. /* assemblelist() : アセンブルリスト出力 */
  697. /*****************************************/
  698. static void assemblelist(void)
  699. {
  700.      reset(PcodeSourceName) ;   /* P-codeソースファイルのオープン       */
  701.  
  702.      printf("\n ADDR   OP   P      Q    P-code source statement\n");
  703.      printf(  "================================================\n");
  704.  
  705.      pc  = 0 ;
  706.  
  707.      for(;;) {
  708.       ch=readc();                       /* 行の最初の文字             */
  709.       switch(ch) {
  710.        case 'N' :
  711.        case 'F' :
  712.        case 'Q' :
  713.        case ';' :
  714.        case 'L' :  printf("                         %c",ch);
  715.            while(!eoln()) printf("%c",readc());
  716.            printf("\n");
  717.            readln();
  718.            if(ch=='Q') {
  719.             if(codesize != objsize)
  720.              printf(" %4d:\n   ~: constant data\n %4d:\n",
  721.                            codesize,objsize-1) ;
  722.                     fclose(pcsfile) ;   /* ソースファイルのクローズ   */
  723.             return;
  724.            }
  725.            break;
  726.  
  727.        case ' ' :  printf(" %4d: %3d %3d %6d",
  728.                pc, store[pc].vo.cdop, store[pc].vo.cdp ,
  729.                    store[pc].vo.cdq);
  730.            pc++;
  731.            printf("    %c",ch);
  732.            while(!eoln()) printf("%c",readc());
  733.            printf("\n");
  734.            readln();
  735.            break;
  736.       }
  737.      }
  738. }
  739.  
  740. /***************************************/
  741. /* main() : P-codeアセンブラメイン処理 */
  742. /***************************************/
  743. int main(int argc,char *argv[])
  744. {
  745.      codesize = atoi(argv[1]) ;         /* 命令コードの数             */
  746.      PcodeSourceName = argv[2] ;        /* P-codeソースファイル名     */
  747.      CompVersion     = argv[3] ;        /* コンパイラのバージョン     */
  748.      init();                            /* 各種初期設定               */
  749.      generate();                        /* アセンブル                 */
  750.      fclose(pcsfile)  ;                 /* ソースファイルのクローズ   */
  751.  
  752.      for(pc=0;pc<codesize;pc++) {       /* qオペランドの補正処理         */
  753.       op = store[pc].vo.cdop ;
  754.       if((/*lao*/ op == 5) || (/*ldox*/ op == 1 || (105<=op && op<=109) )
  755.                            || (/*srox*/ op == 3 || (75<=op && op<=79) ) )
  756.        store[pc].vo.cdq += objsize ;
  757.      }
  758.  
  759.      putobject((char*)&start,sizeof(start)) ; /* オブジェクト開始合図 */
  760.      putobject((char*)store,objsize*sizeof(_store)) ; /* オブジェクト出力*/
  761.      if(fflush(objfile) == EOF) paerr(3) ;
  762.      if(fclose(objfile) == EOF) paerr(3) ;
  763.                  /* クローズできなければ書き込み失敗の可能性がある    */
  764.  
  765.      fputs(         " *** Assemble completed. ***\n",stderr);
  766.      fprintf(stderr," *** code = %5d words  constant data = %5d words ***\n",
  767.                                 codesize,       objsize-codesize);
  768.  
  769.     if(argc==5) assemblelist();         /* アセンブルリストの出力     */
  770.  
  771.     return(0) ;                         /* 正常終了                   */
  772. }
  773.